﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

// Libreria JukeBoxLib
namespace JukeBoxLib
{
    public class Track
    {
        TagLib.File _tag;
        private List<Track> _duplicates;
        public IEnumerable<Track> Duplicates {
            get
            {
                return _duplicates;
            }
        }

        public Track(string filename) : this()
        {
            System.IO.FileInfo fileinfo = new System.IO.FileInfo(filename);
            if (!fileinfo.Exists)
                return ;

            try
            {
                _tag = TagLib.File.Create(filename);
            }
            catch (Exception)
            {
            }
            
            this.FileName = fileinfo.FullName;
            this.Length = fileinfo.Length;

            this.CRC = new HexVal(CalculateCRC());
                

        }

        private int CalculateCRC()
        {
            long start = 0; 
            long end = this.Length;
            if (_tag != null)
            {
                start = _tag.InvariantStartPosition;
                end = _tag.InvariantEndPosition;
            }
            System.IO.FileStream fs = System.IO.File.OpenRead(this.FileName);
            byte[] fbuffer = new byte[end - start];
            fs.Seek(start, System.IO.SeekOrigin.Begin);
            fs.Read(fbuffer, 0, (int)(end - start));
            fs.Close();
            return CRC32.Compute(fbuffer);
        }

        public string Album
        {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.Album;
            }
            set
            {
                _tag.Tag.Album = value;
            }
        }
        public string Title
        {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.Title;
            }
            set
            {
                if (_tag == null) return;
                _tag.Tag.Title = value;
            }
        }
        public string Artists {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.JoinedPerformers;
            }
            set
            {
                //_tag.Tag.JoinedPerformers = value;
            }
        }
        public uint Year
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Tag.Year;
            }
            set
            {
                _tag.Tag.Year = value;
            }
        }
        public string AlbumArtists
        {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.JoinedAlbumArtists;
            }
            set
            {
                //_tag.Tag.JoinedAlbumArtists = value;
            }
        }
        public string BPM { get; set; }
        public string Composers
        {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.JoinedComposers;
            }
            set
            {
                //_tag.Tag.JoinedComposers = value;
            }
        }
        public string Genre { get; set; }
        public string CopyrightMessage { get; set; }
        public string Date { get; set; }
        public string EncodingTime { get; set; }
        public string PlaylistDelay { get; set; }
        public string OrginalReleaseTime { get; set; }
        public string RecordingTime { get; set; }
        public string ReleaseTime { get; set; }
        public string TaggingTime { get; set; }
        public string EncodedBy { get; set; }
        public string Lyric { get; set; }
        public TimeSpan Duration 
        {
            get
            {
                if (_tag == null) return new TimeSpan(0,0,0);
                return _tag.Properties.Duration;
            }
            set
            {
                //_tag.Properties.Duration = value;
            }
        }
        public int AudioBitrate 
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Properties.AudioBitrate;
            }
            set
            {
                //_tag.Properties.AudioBitrate = value;
            }
        }
        public string InvolvedPeopleList { get; set; }
        public string ContentGroupDescription { get; set; }
        public string Subtitle { get; set; }
        public string InitialKey { get; set; }
        public string Language { get; set; }
        public long Length { get; set; }
        public string MusicianCreditsList { get; set; }
        public string MediaType { get; set; }
        public string Mood { get; set; }
        public string OrginalTitle { get; set; }
        public string OrginalFilename { get; set; }
        public string OrginalLyricist { get; set; }
        public string OrginalArtist { get; set; }
        public string OrginalReleaseYear { get; set; }
        public string FileOwner { get; set; }
        public string LeadArtist { get; set; }
        public string BandArtist { get; set; }
        public string Conductor {
            get
            {
                if (_tag == null) return "";
                return _tag.Tag.Conductor;
            }
            set { _tag.Tag.Conductor = value; }
        }
        public string Interpreted { get; set; }
        public string Partofset { get; set; }
        public string ProducedNotice { get; set; }
        public string Publisher { get; set; }
        public uint TrackNumber
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Tag.Track;
            }
            set
            {
                _tag.Tag.Track = value;
            }
        }
        public uint TrackCount
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Tag.TrackCount;
            }
            set
            {
                _tag.Tag.TrackCount = value;
            }
        }
        public uint DiscNumber 
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Tag.Disc;
            }
            set
            {
                _tag.Tag.Disc = value;
            }
        }
        public uint DiscCount
        {
            get
            {
                if (_tag == null) return 0;
                return _tag.Tag.DiscCount;
            }
            set
            {
                _tag.Tag.DiscCount = value;
            }
        }
        public string RecordingDate { get; set; }
        public string InternetRadioStationName { get; set; }
        public string InternetRadioStationOwner { get; set; }
        public string AlbumSortOrder { get; set; }
        public string PreformerSortOrder { get; set; }
        public string TitleSortOrder { get; set; }
        public string ISRC { get; set; }
        public string SoftwareHardwareUsedForEncoding { get; set; }
        public string SetSubtitle { get; set; }
        public bool ID3v1
        {
            get
            {
                if (_tag == null) return false;
                return _tag.TagTypes == TagLib.TagTypes.Id3v1;
            }
            set { }
        }
        public bool ID3v2
        {
            get
            {
                if (_tag == null) return false;
                return _tag.TagTypes == TagLib.TagTypes.Id3v2;
            }
            set { }
        }
        public string Path { get; set; }
        public string FileName { get; set; }
        public HexVal CRC { get; set; }
        public string FileType { get; set; }

        public bool HasPicture
        {
            get
            {
                if (_tag == null) return false;
                return _tag.Tag.Pictures != null;
            }
        }

        public Track()
        {
            _duplicates = new List<Track>();
        }

        public void Add(Track track)
        {
            _duplicates.Add(track);
        }

        public bool IsEqual(Track t)
        {
            return (this.Artists.ToLower() == t.Artists.ToLower() &&
                this.Title.ToLower() == t.Title.ToLower()) 
                || this.CRC == t.CRC;
        }
    }

    public class HexVal
    {
        public Int32 Value { get; set; }

        public HexVal()
        {
        }

        public HexVal(int v)
        {
            this.Value = v;
        }

        public static bool operator ==(HexVal h1, HexVal h2)
        {
            return h1.Value == h2.Value;
        }

        public static bool operator !=(HexVal h1, HexVal h2)
        {
            return h1.Value != h2.Value;
        }

        public override bool Equals(object obj)
        {            
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        
        public override string ToString()
        {
            return this.Value.ToString("X");
        }
    }

}
